package club.vann.kafka.mock.service;

import club.vann.kafka.mock.common.model.consts.ConstantCharacter;
import club.vann.kafka.mock.kafka.KafkaProducer;
import club.vann.kafka.mock.kafka.KafkaTopicFactory;
import cn.hutool.core.util.RandomUtil;
import com.cyberx.lunyu.RealizedVolatilityOuterClass;
import jakarta.annotation.Nullable;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

@RequiredArgsConstructor
@Service
public class RealizedVolatilityService {
  private final KafkaProducer kafkaProducer;

  /**
   * 推送realized volatility数据。
   *
   * @param tradeDateString 交易日期
   */
  public void publisher(@Nullable String tradeDateString) {
    LocalDate tradeDate;
    if (ObjectUtils.isEmpty(tradeDateString)) {
      tradeDate = LocalDate.now().minusDays(1);
    } else {
      tradeDate = LocalDate.parse(tradeDateString, DateTimeFormatter.BASIC_ISO_DATE);
    }
    String btcSym = "BINANCE_SPOT_BTC_USDT";
    RealizedVolatilityOuterClass.RealizedVolatility btcRealizedVolatility =
        build(tradeDate, btcSym);
    this.kafkaProducer.send(
        KafkaTopicFactory.REALIZED_VOLATILITY_INPUT,
        symFormat(btcSym),
        btcRealizedVolatility.toByteArray());

    String ethSym = "BINANCE_SPOT_ETH_USDT";
    RealizedVolatilityOuterClass.RealizedVolatility ethRealizedVolatility =
        build(tradeDate, ethSym);
    this.kafkaProducer.send(
        KafkaTopicFactory.REALIZED_VOLATILITY_INPUT,
        symFormat(ethSym),
        ethRealizedVolatility.toByteArray());
  }

  /**
   * Sym格式为[EXCHANGE]_[TYPE]_[XXX]_[YYY]
   *
   * <p>数据中sym格式为XXX_YYY，需要格式化为 [EXCHANGE]_[TYPE]_[XXX]/[YYY]
   *
   * @param sym Sym
   * @return 格式化后的Sym
   */
  private String symFormat(String sym) {
    if (sym == null) {
      return sym;
    }
    int lastIndexOf = sym.lastIndexOf(ConstantCharacter.UNDERLINE);
    return sym.substring(0, lastIndexOf) + ConstantCharacter.SLASH + sym.substring(lastIndexOf + 1);
  }

  private RealizedVolatilityOuterClass.RealizedVolatility build(LocalDate tradeDate, String sym) {
    return RealizedVolatilityOuterClass.RealizedVolatility.newBuilder()
        .setTradeDate(tradeDate.format(DateTimeFormatter.BASIC_ISO_DATE))
        .setSym(sym)
        .setTradeCount(RandomUtil.randomInt(10, 10000))
        .setVol1M(RandomUtil.randomDouble(0.01, 0.99))
        .setVol1D(RandomUtil.randomDouble(0.01, 0.99))
        .setVolAnnual(RandomUtil.randomDouble(0.01, 0.99))
        .setTimestamp(System.currentTimeMillis())
        .build();
  }
}
